<?php
    if(class_exists('UtCreateItem') === false)
    {
        Class UtCreateItem extends UtItemInfo
        {
            private static $_instance = null;
            private $_createId = 0;
            private $_createOpt = 0;
            private $_createLvlSkillLuck = 0;
            private $_createExe = 0;
            private $_createDurability = 0;
            private $_newItem = "";
            private $_createType = 0;
            private $_createSerial = 0;
            private $_createHarmony = 0;
            private $_createSocket = 0;
            private $_createAncient = 0;
            private $_versionCreate = 0;
            private $_createLevel380 = 0;


            public static function getStance()
            {
                if(self::$_instance === null)
                    self::$_instance = new self;

                return self::$_instance;
            }

            protected function __construct()
            {

            }

            protected function returnHexItem($tipo,$id,$lvl = 0,$opt = 0,$exe = array(),$skill = false,$luck = false ,$dura = 0 ,$anc = 0,$lvl_380 = false,$harm = array(),$sock = array(),$version)
            {
                $this->_versionCreate = $version;
                $this->clearCreate();
                switch($this->_versionCreate)
                {
                    case 2:
                        $this->_newItem = str_repeat("F",32);
                        $this->_createType = $tipo; 
                        $this->_createOpt = $opt;                                                                
                        $this->createIdItem($id);
                        $this->createOptItem();
                        $this->createLevelSkillLuckOptItem($lvl,$skill,$luck);
                        $this->createDuraItem($dura,$lvl);
                        $this->createExeItem($exe);
                        $this->createAncient($anc);
                        $this->createTypeLevel380($lvl_380);
                        $this->createHarmony($harm);
                        $this->createSocket($sock);
                        $this->finishCreate();
                        $this->clearCreate();
                        return strtoupper($this->_newItem);
                        break;
                    case 1:
                        $this->_newItem = str_repeat("F",20);
                        $this->_createType = $tipo; 
                        $this->_createOpt = $opt;                                                                
                        $this->createIdItem($id);
                        $this->createOptItem();
                        $this->createLevelSkillLuckOptItem($lvl,$skill,$luck);
                        $this->createDuraItem($dura,$lvl);
                        $this->createExeItem($exe);
                        $this->finishCreate();
                        $this->clearCreate();
                        return strtoupper($this->_newItem);
                        break;
                    default:
                        $this->_newItem = str_repeat("F",20);
                        $this->_createType = $tipo; 
                        $this->_createOpt = $opt;                                                                
                        $this->createIdItem($id);
                        $this->createOptItem();
                        $this->createLevelSkillLuckOptItem($lvl,$skill,$luck);
                        $this->createDuraItem($dura,$lvl);
                        $this->createExeItem($exe);
                        $this->finishCreate();
                        $this->clearCreate();
                        return strtoupper($this->_newItem);
                        break;
                }
            }

            private function createIdItem($id)
            {
                if($this->_versionCreate > 1)
                {  
                    $this->_createId = (($id & 0xFF));
                    $this->_createId = dechex($this->_createId);

                    return $this->_createId;
                }

                $this->_createId = dechex(($id & 0x1F) | (($this->_createType << 5) & 0xE0));
                return $this->_createId;
            }

            private function createOptItem()
            {
                switch($this->_createOpt)
                {
                    case 4:  $this->_createLvlSkillLuck += 1; 
                        break;
                    case 8:  $this->_createLvlSkillLuck += 2; 
                        break;
                    case 12: $this->_createLvlSkillLuck += 3; 
                        break;
                    case 16: $this->_createLvlSkillLuck += 0; 
                        break;
                    case 20: 
                        $this->_createLvlSkillLuck += 1;
                        $this->_createExe += 64;
                        break;
                    case 24: 
                        $this->_createLvlSkillLuck += 2; 
                        $this->_createExe += 64;
                        break;
                    case 28: 
                        $this->_createLvlSkillLuck += 3;
                        $this->_createExe += 64;
                        break;
                }
                return true;
            }

            private function createLevelSkillLuckOptItem($lvl,$skill,$luck)
            {

                $this->_createLvlSkillLuck += $lvl * 8;
                $this->_createLvlSkillLuck += ($skill === true) ? 128 : 0;
                $this->_createLvlSkillLuck += ($luck === true) ? 4 : 0;
                $this->_createLvlSkillLuck = dechex($this->_createLvlSkillLuck);
                return $this;
            }

            private function createDuraItem($dura,$level)
            {

                if($level > 0 && $level < 5)
                {
                    $dura = $dura + $level;
                }
                elseif($level >= 5 && $level < 10)
                {
                    $dura = $dura + 4 + (($level - 4) * 2);
                }
                elseif($level >= 10 && $level < 12)
                {
                    $dura = $dura + 14 + (($level - 9) * 3);
                }
                elseif($level >= 12)
                {
                    $dura = $dura + 20 + (($level - 11) * 6);
                }

                $dura = $dura > 255 ? 255 : ($dura < 0 ? 0 : $dura);

                return $this->_createDurability = dechex($dura);
            }

            private function createExeItem($exe)
            {
                switch($this->_versionCreate)
                {
                    case 1:
                        $this->_createExe += ($this->_createType > 7 ) ? 128 : 0;    
                        break;
                    default:

                        break;
                }
                $this->_createExe += ((bool)$exe[0] == true) ? 32 : 0;
                $this->_createExe += ((bool)$exe[1] == true) ? 16 : 0;
                $this->_createExe += ((bool)$exe[2] == true) ? 8 : 0;
                $this->_createExe += ((bool)$exe[3] == true) ? 4 : 0;
                $this->_createExe += ((bool)$exe[4] == true) ? 2 : 0;
                $this->_createExe += ((bool)$exe[5] == true) ? 1 : 0;
                $this->_createExe = dechex($this->_createExe);
                return $this;
            }

            private function finishCreate()
            {
                switch($this->_versionCreate)
                {
                    case 2:
                        $this->_newItem = $this->fix($this->_createId);
                        $this->_newItem .= $this->fix($this->_createLvlSkillLuck);
                        $this->_newItem .= $this->fix($this->_createDurability);
                        $this->_newItem .= $this->fix("",8);
                        $this->_newItem .= $this->fix($this->_createExe);
                        $this->_newItem .= $this->fix($this->_createAncient,2);
                        $this->_newItem .= $this->fix($this->_createLevel380);
                        $this->_newItem .= $this->fix($this->_createHarmony);
                        $this->_newItem .= $this->fix($this->_createSocket,10);
                        $this->_newItem =  parent::alterSerial($this->_newItem); 
                        return true;
                        break;
                    case 1:
                        $this->_newItem = $this->fix($this->_createId);  
                        $this->_newItem .= $this->fix($this->_createLvlSkillLuck);
                        $this->_newItem .= $this->fix($this->_createDurability);
                        $this->_newItem .= $this->fix("",8);
                        $this->_newItem .= $this->fix($this->_createExe);
                        $this->_newItem .= str_repeat("F",4);
                        $this->_newItem = parent::alterSerial($this->_newItem);
                        return true;
                        break;

                    default:
                        $this->_newItem = $this->fix($this->_createId);  
                        $this->_newItem .= $this->fix($this->_createLvlSkillLuck);
                        $this->_newItem .= $this->fix($this->_createDurability);
                        $this->_newItem .= $this->fix("",8);
                        $this->_newItem .= $this->fix($this->_createExe);
                        $this->_newItem .= str_repeat("F",4);
                        $this->_newItem = parent::alterSerial($this->_newItem);
                        return true;
                        break;
                }
            }

            private function fix($val, $size = 2)
            {
                return str_pad($val, $size, "0", STR_PAD_LEFT);
            }

            private function clearCreate()
            {
                $this->_createId = 0;
                $this->_createType = 0;
                $this->_createOpt = 0;
                $this->_createLvlSkillLuck = 0;
                $this->_createDurability = 0;
                $this->_createSerial = 0;
                $this->_createHarmony = 0;
                $this->_createSocket = 0;
                $this->_createAncient = 0;
                $this->_createExe = 0;   
                $this->_createLevel380 = 0;             
            }

            private function createAncient($anc)
            {
                switch($anc)
                {
                    case 0: $this->_createAncient = 0 ; break;
                    case 1: $this->_createAncient = 5 ; break;
                    case 2: $this->_createAncient = 9 ; break;
                    default: $this->_createAncient = 0 ; break;
                }
                return $this->_createAncient;  
            }

            private function createTypeLevel380($level_380)
            {
                $this->_createLevel380 = dechex($this->_createType).((bool)$level_380 == true ? "8" : "0");
                return $this;
            }

            private function createHarmony($harm)
            {
                if(strlen($harm) == 2)

                    return $this->_createHarmony = ($harm[0]) . ($harm[1]);

                else 

                    return $this->_createHarmony = "00";  
            }

            private function createSocket($sock)
            {
                if(is_array($sock))
                {

                    for($x = 1 ; $x < 6; $x ++)
                    {

                        if(!array_key_exists($x,$sock))
                        {

                            $value .= $this->fix(dechex(0) . dechex(0),2);            
                        }
                        else
                        {                                                                       
                            $value .= $this->fix($sock[$x][0] . $sock[$x][1],2);
                        }

                    }
                    return $this->_createSocket = strtoupper($value);
                    unset($value);
                }
                else

                    return $this->_createSocket = "0000000000";
            }

            protected function __destroy()
            {
                $this->clearCreate();
            }
        }
    }
?>